我的Bilibili频道:香芋派Taro
我的个人博客:taropie0224.github.io(阅读体验更佳)
我的公众号:香芋派的烘焙坊
我的音频技术交流群:1136403177
我的个人微信:JazzyTaroPie

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution
{
public:
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q)
{
if (root == nullptr || root == p || root == q)
{
return root;
}
TreeNode *left = lowestCommonAncestor(root->left, p, q);
TreeNode *right = lowestCommonAncestor(root->right, p, q);
// p和q分布在当前root的两侧子树上那么最近公共祖先就是当前root
if (left == nullptr && right == nullptr)
return nullptr; // 1.
if (left == nullptr)
return right; // 3.
if (right == nullptr)
return left; // 4.
return root; // 2. if(left != null and right != null)
}
};

思路

终止条件:

  1. 当越过叶节点,则直接返回 nul

  2. 当root 等于 p,q ,则直接返回 root

递推工作:

  1. 开启递归左子节点,返回值记为 left
  2. 开启递归右子节点,返回值记为 right

返回值:根据 left 和 right ,可展开为四种情况;

  1. 当 left 和 right 同时为空 :说明 root 的左 / 右子树中都不包含 p,q ,返回 null
  2. 当 left 和right 同时不为空 :说明 p,q 分列在 root 的 异侧 (分别在 左 / 右子树),因此 root 为最近公共祖先,返回 root
  3. 当 left 为空 ,right 不为空 :p,q 都不在 root 的左子树中,直接返回 right 。具体可分为两种情况:p,q 其中一个在 root 的 右子树 中,此时 right 指向 p(假设为 p );p,q 两节点都在 root 的 右子树 中,此时的 right 指向 最近公共祖先节点
  4. 当 left 不为空 , right 为空 :与情况 3. 同理

为什么说找到一个就可以,因为

  1. 如果 q 是 p 的子孙, 那么肯定先找到的是p,那么p就是 p和q 的公共祖先

  2. 如果 q 不是 p 的子孙, 那么在到达p之前,肯定会先到达p和q的公共祖先r,然后分别到达p和q,也就可以返回r了